import { path } from "@tauri-apps/api";
import { exists, mkdir, readDir, readFile } from "@tauri-apps/plugin-fs";
import { IOpenScopePluginBase } from "../interfaces/pluginInterfaces/IOpenScopePluginBase";
import { readUriToText } from "../readFileToText/openTextFile";
import { RadarScreen } from "../RadarCanvasDrawer";
import { fetch } from "@tauri-apps/plugin-http";
import { RenderData } from "./RadarRenderData";
import { loadCurFileToBase64 } from "../fileLoader/loadCurFile";
import { IRadarRenderData } from "../interfaces/pluginInterfaces/IRenderData";

class ExternalPluginData {
    pluginPath: string = '';
    plugins: Array<IOpenScopePluginBase> = [];

    async loadPluginFromPath(uri: string): Promise<void> {
        let rawPluginStr = await readUriToText(uri);
        rawPluginStr = rawPluginStr.replace(`"use strict";`, '').replace('Object.defineProperty(exports, "__esModule", { value: true });', '');
        while (rawPluginStr.lastIndexOf(`var `) != -1) {
            rawPluginStr = rawPluginStr.replace(`var `, 'let ');
        }
        const plugin: IOpenScopePluginBase = eval(`(${rawPluginStr.replace(`"use strict";`, '')})`)();
        plugin.invokeRadarRedraw = () => {
            RadarScreen.draw();
        };
        plugin.fetch = (url: URL | Request | string, init?: RequestInit): Promise<Response> => {
            return fetch(url, init);
        };
        plugin.getRenderDataInstance = () => RenderData as unknown as IRadarRenderData;
        plugin.readTextFile = async (uri) => {
            return await readUriToText(uri);
        };
        plugin.readBufferFile = async (uri) => {
            return await readFile(uri);
        };
        plugin.readCurFileToBase64 = async (uri: string) => {
            return (await loadCurFileToBase64(uri)).value;
        }
        plugin.setCurFileAsCursor = async (uri: string) => {
            const base64 = await loadCurFileToBase64(uri);
            console.log(base64);
            document.body.style.cursor = `url("${base64.value}") ${base64.centerX} ${base64.centerY}, auto`;
        }
        this.plugins.push(plugin);
        const wd = await path.dirname(uri);
        plugin.onInitialized(wd);
    }

    async init() {
        this.plugins = [];
        const localDataPath = await path.appLocalDataDir();
        const ldpExistence = await exists(localDataPath);
        if (!ldpExistence) {
            await mkdir(localDataPath);
        }
        this.pluginPath = await path.join(localDataPath, 'plugins');
        const existence = await exists(this.pluginPath);
        if (!existence) {
            await mkdir(this.pluginPath);
        }
        const entries = await readDir(this.pluginPath);
        for (const entry of entries) {
            if (entry.isDirectory) {
                const entryPath = await path.join(this.pluginPath, entry.name, 'plugin.js');
                await this.loadPluginFromPath(entryPath);
            }
        }
    }
}

export const PluginData = new ExternalPluginData();